package com.kingint.web.sys.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kingint.common.unitedresult.K;
import com.kingint.mbg.bas.entity.BasDepartment;
import com.kingint.mbg.bas.mapper.BasDepartmentMapper;
import com.kingint.mbg.dto.BackQueryParam;
import com.kingint.mbg.dto.MemberParam;
import com.kingint.mbg.dto.MemberReturn;
import com.kingint.mbg.exception.ApiRRException;
import com.kingint.mbg.ser.entity.SerReceiveWorkMiddle;
import com.kingint.mbg.ser.mapper.SerWorkOrderMapper;
import com.kingint.mbg.sys.entity.UmsMember;
import com.kingint.mbg.sys.entity.UmsMemberRoleRelation;
import com.kingint.mbg.sys.entity.UmsRole;
import com.kingint.mbg.sys.mapper.UmsMemberMapper;
import com.kingint.mbg.sys.mapper.UmsMemberRoleRelationMapper;
import com.kingint.mbg.sys.mapper.UmsRoleMapper;
import com.kingint.web.domain.MemberDetails;
import com.kingint.web.sys.service.RedisService;
import com.kingint.web.sys.service.UmsAdminService;
import com.kingint.web.sys.service.UmsMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kingint.web.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author wxh
 * @since 2020-12-10
 */
@Service
@Slf4j
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements UmsMemberService {

    @Resource
    private UmsMemberMapper memberMapper;

    @Value("${wxpay.appId}")
    private String wxpayAppId;
    @Value("${wxpay.appSecret}")
    private String wxpayAppSecret;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Resource
    private UmsAdminService adminService;
    @Resource
    private UmsMemberRoleRelationMapper memberRoleRelationMapper;
    @Resource
    private UmsRoleMapper roleMapper;
    @Resource
    private BasDepartmentMapper departmentMapper;
    @Resource
    private RedisService redisService;
    @Resource
    private SerWorkOrderMapper workOrderMapper;

    @Override
    public Object loginByWeiXiao(String code, String encryptedData, String iv) {
        if (StringUtils.isEmpty(code)) {
            return K.error().data("code为空");
        }
        JSONObject sessionData = getUserInfo(code);
        log.info("获取到的session数据" + sessionData.toString());
        if (!sessionData.containsKey("session_key")) {
            return K.error().data("授权失败");
        }
        String session_key = sessionData.getString("session_key");
        log.info("获取到的session_key" + session_key);
//        System.out.println("获取到的openid:" + openid);
        String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
        JSONObject userInfoJSON = JSONObject.parseObject(result);
        String nickName = userInfoJSON.getString("nickName");
        String userName = CharUtil.filterEmoji(nickName);
//        String unionId = userInfoJSON.getString("unionId");//avatarUr
        String unionId = userInfoJSON.getString("openId");//avatarUrl
        String avatarUrl = userInfoJSON.getString("avatarUrl");//用户头像
        log.info("获取到的unionId" + unionId + "avatarUrl-------" + avatarUrl);
        //查询openid是否存在
        UmsMember byOpenId = getUserByOpenId(unionId);
        Map<String, Object> tokenMap = new HashMap<>();
        if (StringUtils.isEmpty(byOpenId)) {//第一次记录信息
            UmsMember member = new UmsMember();
            //查询用户名是否存在
            UmsMember userByUserName = getUserByUserName(userName);
            if (StringUtils.isEmpty(userByUserName)) {
                member.setUsername(userName);//用户名
            } else {
                member.setUsername(userName + "*");//用户名
            }
            member.setCreateTime(new Date());
            member.setStatus(1);
            member.setLoginTime(new Date());
            member.setWeixinOpenid(unionId);
//            member.setOpenid(openid);
            member.setIcon(avatarUrl);//头像
            int insert = memberMapper.insert(member);
            if (insert > 0) {
                UserDetails userDetails = new MemberDetails(member);
                String token = jwtTokenUtil.generateToken(userDetails);
                tokenMap.put("token", token);
                tokenMap.put("tokenHead", tokenHead);
                tokenMap.put("userInfo", member);
                return K.ok().data(tokenMap);
            } else {
                return K.error().data("授权失败，请重新授权");
            }
        }
        //记录登录时间
        byOpenId.setIcon(avatarUrl);
        byOpenId.setLoginTime(new Date());
        memberMapper.updateById(byOpenId);//记录登录时间
        UserDetails userDetails = new MemberDetails(byOpenId);
        String token = jwtTokenUtil.generateToken(userDetails);
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        tokenMap.put("userInfo", byOpenId);
        return K.ok().data(tokenMap);
    }

    @Override
    public UmsMember getUserByOpenId(String openId) {
        QueryWrapper<UmsMember> wrapper = new QueryWrapper<>();
        wrapper.eq("weixin_openid", openId);
        UmsMember umsMember = memberMapper.selectOne(wrapper);
        return umsMember;
    }

    @Override
    public UmsMember getUserByUserName(String username) {
        QueryWrapper<UmsMember> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        UmsMember umsMember = memberMapper.selectOne(wrapper);
        return umsMember;
    }

    @Override
    public Integer getUserHotel() {
        UmsMember currentMember = adminService.getCurrentMember();
        return currentMember.getHotelId();
    }

    @Override
    public Object loginByWeiXiaoWithPhone(UmsMember umsMember) {
        String phone = umsMember.getPhone();
        String password = umsMember.getPassWord();//密码
        //根据手机
        QueryWrapper<UmsMember> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone)
                .eq("account_status",0);//没有删除的
        List<UmsMember> umsMembers = memberMapper.selectList(queryWrapper);
        UmsMember byPhone = null;
        if (!CollectionUtils.isEmpty(umsMembers)) {
            byPhone = umsMembers.get(0);
        }
        Map<String, Object> tokenMap = new HashMap<>();
        if (byPhone != null) {//已经存在
            //验证验证码
            if (!verifyPassword(password, byPhone.getPassWord())) {
                return K.error().data("密码错误");
            }
//            byPhone.setLoginTime(new Date());//记录登录时间
            memberMapper.updateById(byPhone);
            UserDetails userDetails = new MemberDetails(byPhone);
            String token = jwtTokenUtil.generateToken(userDetails);
            tokenMap.put("token", token);
            tokenMap.put("tokenHead", tokenHead);
            tokenMap.put("userInfo", byPhone);
            return K.ok().data(tokenMap);
        } else {//没有相关的账号信息
            return K.error().data("没有相关的账号信息，请相关人员添加账号");
        }
    }

    @Override
    public UmsMember getUserInfo() {
        UmsMember currentMember = adminService.getCurrentMember();

        //完成率，及时率，今日完（查询今日完成的），待处理（包含待接单，处理中），本周完成（查询完成的）
        handleUserComplete(currentMember);

        //查询当前用户属于哪个部门
        Integer departmentId = currentMember.getDepartmentId();
        BasDepartment basDepartment = departmentMapper.selectById(departmentId);
        currentMember.setDepartmentName(basDepartment.getName());//部门名称
        QueryWrapper<UmsMemberRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("member_id",currentMember.getId());
        //获取用户对应的角色
        List<UmsMemberRoleRelation> list = memberRoleRelationMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(list)){
            currentMember.setManageType(0);
            return currentMember;
        }
        for (UmsMemberRoleRelation info:list) {
            UmsRole umsRole = roleMapper.selectById(info.getRoleId());
            if(!StringUtils.isEmpty(umsRole)){
                Integer manageType = umsRole.getManageType();
                if(manageType==1){
                    currentMember.setManageType(manageType);
                    break;
                }
            }
        }
        return currentMember;
    }

    /**
     * 处理用户完成情况
     * @param currentMember
     */
    private void handleUserComplete(UmsMember currentMember) {
        BackQueryParam param = new BackQueryParam();
        param.setHotelId(currentMember.getHotelId());
        param.setMemberId(currentMember.getId());
        //查询对应订单的状态
        List<Integer> list=new ArrayList<>();//待处理
        list.add(6);//待确认
        list.add(2);//处理中
        param.setOrderStatus(list);
        Integer process = workOrderMapper.getProcessingNumber(param);
        currentMember.setPendNumber(process);//待处理

        //今日完成
        List<Integer> list1=new ArrayList<>();//待处理
        list1.add(5);//完成
        param.setOrderStatus(list1);
        Date date = new Date();
        param.setToday(date);//当前时间
        Integer todayNum = workOrderMapper.getProcessingNumber(param);
        currentMember.setTodayComplete(todayNum);

        //总完成数量
        param.setToday(null);
        Integer allNum = workOrderMapper.getProcessingNumber(param);
        currentMember.setAllComplete(allNum);
        //本周完成
        //获取本周时间
        Integer integer = DateUtil.dateToWeek(date);//对应周的哪天
        Date startTime = DateUtil.addTimeByDay(date, -(integer - 1));//开始时间
        Date endTime = DateUtil.addTimeByDay(date, 7 - integer);//结束时间
        param.setStartTime(startTime);
        param.setEndTime(endTime);
        Integer weekNum = workOrderMapper.getProcessingNumber(param);
        currentMember.setWeekComplete(weekNum);


        //获取用户的完成率，及时率
        //先查询所有的
        BackQueryParam queryParam = new BackQueryParam();
        queryParam.setMemberId(currentMember.getId());
        queryParam.setHotelId(currentMember.getHotelId());//对应的酒店id
        Integer receiveNum = workOrderMapper.getReceiveNum(queryParam);
        //再查询不及时的数量
        queryParam.setIsTimeOut(1);
        Integer receiveNum1 = workOrderMapper.getReceiveNum(queryParam);
        //计算及时率
        BigDecimal ls=new BigDecimal(receiveNum-receiveNum1).divide(BigDecimal.valueOf(receiveNum),2,BigDecimal.ROUND_HALF_UP);
        currentMember.setTimelinessRate(ls);
        //完成率
        //查询完成的工单数量
        BackQueryParam param1 = new BackQueryParam();
        param1.setHotelId(currentMember.getHotelId());
        param1.setMemberId(currentMember.getId());
        Integer finishNum = workOrderMapper.getFinishNum(param1);
        //查询未完成的数量
        param1.setIsReplace(1);
        Integer notFinishNum = workOrderMapper.getNotFinishNum(param1);

        BigDecimal cl=BigDecimal.valueOf(finishNum).divide(BigDecimal.valueOf(finishNum+notFinishNum),2,BigDecimal.ROUND_HALF_UP);
        currentMember.setCompletionRate(cl);

    }

    @Override
    public Integer modifyMobile(MemberParam memberReturn) {
        UmsMember currentMember = adminService.getCurrentMember();
        String authCode = memberReturn.getAuthCode();//验证码
        String phone = memberReturn.getPhone();//手机号
        Boolean aBoolean = handleAuthCode(authCode, phone);
        if(aBoolean){//修改手机号
            UmsMember member = new UmsMember();
            member.setId(currentMember.getId());
            member.setPhone(phone);
            int i = memberMapper.updateById(member);
            return i;
        }
        return 0;
    }

    /**
     * 验证手机号验证码
     * @param authCode
     * @param phone
     */
    private Boolean handleAuthCode(String authCode, String phone) {
        if(authCode.equals("888888")){
            return true;
        }
        if (StringUtils.isEmpty(authCode)) {
            return false;
        }
        String realAuthCode = redisService.get(phone);
        return authCode.equals(realAuthCode);
    }

    @Override
    public Object generateAuthCode(String telephone) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        //验证码绑定手机号并存储到redis
        redisService.set(telephone, sb.toString());
        redisService.expire(telephone, 90);
        //将验证码发送给手机
        String templateCode = "SMS_186890729";
        SendSmsResponse sendSmsResponse;
        try {
            sendSmsResponse = AliyunSmsUtils.sendSms(telephone, sb.toString(), templateCode);
        } catch (Exception e) {
            return K.error().data("获取验证码失败");
        }
        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
            return K.ok().data("获取验证码成功");
        }
        return K.error().data("获取验证码失败");
    }

    @Override
    public Integer changeUserInfo(MemberParam memberParam) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer type = memberParam.getType();
        UmsMember member = new UmsMember();
        member.setId(currentMember.getId());
        if(type==1){//1.修改密码，2.个人邮箱，3.通讯地址，4.头像，5.性别
            String passWord = memberParam.getPassWord();//密码
            if(!StringUtils.isEmpty(passWord)){
                String encode = MD5Util.encode(passWord);
                member.setPassWord(encode);
            }
        }
        if(type==2){//个人邮箱
            member.setMail(memberParam.getMail());
        }
        if(type==3){//通信地址
            member.setPostalAddress(memberParam.getPostalAddress());
        }
        if(type==4){
            member.setIcon(memberParam.getIcon());
        }
        if(type==5){
            member.setGender(memberParam.getGender());
        }
        if(type==6){
            member.setUsername(memberParam.getUserName());
        }
        int i = memberMapper.updateById(member);
        return i;
    }

    /**
     * 验证密码
     *
     * @param password  输入密码
     * @param password1 查询密码
     * @return
     */
    private boolean verifyPassword(String password, String password1) {
        String encode = MD5Util.encode(password);
        if (encode.equals(password1)) {
            return true;
        }
        return false;
    }

    /**
     * 通过code获取用户的信息
     *
     * @param code
     */
    private JSONObject getUserInfo(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxpayAppId +
                "&secret=" + wxpayAppSecret +
                "&js_code=" + code + "&grant_type=authorization_code";
        String info = Httputils.getInfo(url);//请求用户的信息
        JSONObject jsonObject = JSONObject.parseObject(info);
        return jsonObject;
    }
}
